// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

mod database;
mod commands;
mod devices;
mod error;

use tauri::{
    Manager, Window,
};
use std::sync::Arc;
use tokio::sync::Mutex;
use serde::{Deserialize, Serialize};
use tracing::{info, error, debug};
use tracing_subscriber;

use devices::DeviceManager;
use database::DatabaseManager;
use commands::*;
use commands::device_control::DeviceControlState;

#[derive(Clone, Serialize)]
struct MenuEventPayload {
    action: String,
    data: Option<serde_json::Value>,
}

#[derive(Serialize, Deserialize, Clone, Debug)]
struct AppSettings {
    language: String,
    theme: String,
    font_size: u32,
    auto_save: bool,
    notifications: bool,
    auto_update: bool,
}

impl Default for AppSettings {
    fn default() -> Self {
        Self {
            language: "zh-CN".to_string(),
            theme: "system".to_string(),
            font_size: 14,
            auto_save: true,
            notifications: true,
            auto_update: false,
        }
    }
}

#[derive(Default)]
struct AppState {
    settings: Arc<std::sync::Mutex<AppSettings>>,
    recent_files: Arc<std::sync::Mutex<Vec<String>>>,
    has_unsaved_changes: Arc<std::sync::Mutex<bool>>,
}

// 设备管理器状态
struct DeviceManagerState {
    manager: Arc<tokio::sync::Mutex<Option<DeviceManager>>>,
}


// === ADB设备管理命令 ===

#[tauri::command]
async fn initialize_device_manager(
    device_state: tauri::State<'_, DeviceManagerState>
) -> Result<(), String> {
    info!("Initializing device manager");
    
    match DeviceManager::new().await {
        Ok(manager) => {
            if let Err(e) = manager.start().await {
                error!("Failed to start device manager: {}", e);
                return Err(format!("Failed to start device manager: {}", e));
            }
            
            let mut state = device_state.manager.lock().await;
            *state = Some(manager);
            
            info!("Device manager initialized successfully");
            Ok(())
        }
        Err(e) => {
            error!("Failed to create device manager: {}", e);
            Err(format!("Failed to initialize device manager: {}", e))
        }
    }
}

#[tauri::command]
async fn scan_adb_devices(
    device_state: tauri::State<'_, DeviceManagerState>
) -> Result<Vec<serde_json::Value>, String> {
    info!("Scanning for ADB devices");
    
    let state = device_state.manager.lock().await;
    if let Some(manager) = state.as_ref() {
        match manager.scan_devices().await {
            Ok(devices) => {
                let device_json: Vec<serde_json::Value> = devices
                    .into_iter()
                    .map(|device| serde_json::to_value(device).unwrap())
                    .collect();
                
                info!("Found {} devices", device_json.len());
                Ok(device_json)
            }
            Err(e) => {
                error!("Device scan failed: {}", e);
                Err(format!("Device scan failed: {}", e))
            }
        }
    } else {
        Err("Device manager not initialized".to_string())
    }
}

#[tauri::command]
async fn connect_adb_device(
    device_id: String,
    device_state: tauri::State<'_, DeviceManagerState>
) -> Result<(), String> {
    info!("Connecting ADB device: {}", device_id);
    
    let state = device_state.manager.lock().await;
    if let Some(manager) = state.as_ref() {
        match manager.connect_device(&device_id).await {
            Ok(_) => {
                info!("Device connected successfully: {}", device_id);
                Ok(())
            }
            Err(e) => {
                error!("Failed to connect device {}: {}", device_id, e);
                Err(format!("Failed to connect device: {}", e))
            }
        }
    } else {
        Err("Device manager not initialized".to_string())
    }
}

#[tauri::command]
async fn disconnect_adb_device(
    device_id: String,
    device_state: tauri::State<'_, DeviceManagerState>
) -> Result<(), String> {
    info!("Disconnecting ADB device: {}", device_id);
    
    let state = device_state.manager.lock().await;
    if let Some(manager) = state.as_ref() {
        match manager.disconnect_device(&device_id).await {
            Ok(_) => {
                info!("Device disconnected successfully: {}", device_id);
                Ok(())
            }
            Err(e) => {
                error!("Failed to disconnect device {}: {}", device_id, e);
                Err(format!("Failed to disconnect device: {}", e))
            }
        }
    } else {
        Err("Device manager not initialized".to_string())
    }
}

#[tauri::command]
async fn take_device_screenshot(
    device_id: String,
    device_state: tauri::State<'_, DeviceManagerState>
) -> Result<Vec<u8>, String> {
    info!("Taking screenshot for device: {}", device_id);
    
    let state = device_state.manager.lock().await;
    if let Some(manager) = state.as_ref() {
        match manager.take_device_screenshot(&device_id).await {
            Ok(screenshot) => {
                info!("Screenshot captured for device: {}", device_id);
                Ok(screenshot)
            }
            Err(e) => {
                error!("Failed to take screenshot for device {}: {}", device_id, e);
                Err(format!("Failed to take screenshot: {}", e))
            }
        }
    } else {
        Err("Device manager not initialized".to_string())
    }
}

#[tauri::command]
async fn get_device_performance(
    device_id: String,
    device_state: tauri::State<'_, DeviceManagerState>
) -> Result<serde_json::Value, String> {
    debug!("Getting performance metrics for device: {}", device_id);
    
    let state = device_state.manager.lock().await;
    if let Some(manager) = state.as_ref() {
        match manager.get_device_performance(&device_id).await {
            Ok(performance) => {
                match serde_json::to_value(performance) {
                    Ok(json) => Ok(json),
                    Err(e) => Err(format!("Failed to serialize performance data: {}", e))
                }
            }
            Err(e) => {
                error!("Failed to get performance for device {}: {}", device_id, e);
                Err(format!("Failed to get device performance: {}", e))
            }
        }
    } else {
        Err("Device manager not initialized".to_string())
    }
}

#[tauri::command]
async fn get_all_adb_devices(
    device_state: tauri::State<'_, DeviceManagerState>
) -> Result<Vec<serde_json::Value>, String> {
    debug!("Getting all ADB devices");
    
    let state = device_state.manager.lock().await;
    if let Some(manager) = state.as_ref() {
        match manager.get_all_devices().await {
            Ok(devices) => {
                let device_json: Vec<serde_json::Value> = devices
                    .into_iter()
                    .map(|device| serde_json::to_value(device).unwrap())
                    .collect();
                Ok(device_json)
            }
            Err(e) => {
                error!("Failed to get all devices: {}", e);
                Err(format!("Failed to get devices: {}", e))
            }
        }
    } else {
        Err("Device manager not initialized".to_string())
    }
}

// Tauri 命令函数 (legacy)
#[tauri::command]
fn hello_world() -> String {
    "Hello from Tauri!".to_string()
}


#[tauri::command]
async fn save_app_settings(
    app: tauri::AppHandle,
    settings: AppSettings,
) -> Result<(), String> {
    let state = app.state::<AppState>();
    *state.settings.lock().unwrap() = settings.clone();
    
    // 这里可以保存到文件
    println!("Saving app settings: {:?}", settings);
    
    Ok(())
}

#[tauri::command]
async fn load_app_settings(app: tauri::AppHandle) -> Result<AppSettings, String> {
    let state = app.state::<AppState>();
    let settings = state.settings.lock().unwrap().clone();
    Ok(settings)
}

#[tauri::command]
async fn update_recent_files(
    app: tauri::AppHandle,
    files: Vec<String>,
) -> Result<(), String> {
    let state = app.state::<AppState>();
    *state.recent_files.lock().unwrap() = files;
    Ok(())
}

#[tauri::command]
async fn get_app_version() -> Result<String, String> {
    Ok(env!("CARGO_PKG_VERSION").to_string())
}

#[tauri::command]
async fn show_open_dialog(_filters: Vec<serde_json::Value>) -> Result<Option<String>, String> {
    // 这里实现文件对话框
    // 临时返回模拟数据
    Ok(Some("path/to/project.smp".to_string()))
}

#[tauri::command]
async fn show_save_dialog(
    default_path: String,
    _filters: Vec<serde_json::Value>,
) -> Result<Option<String>, String> {
    // 这里实现保存对话框
    Ok(Some(default_path))
}

#[tauri::command]
async fn save_current_project() -> Result<(), String> {
    // 实现保存当前项目逻辑
    println!("Saving current project...");
    Ok(())
}

#[tauri::command]
async fn save_project_as(path: String) -> Result<(), String> {
    // 实现另存为逻辑
    println!("Saving project as: {}", path);
    Ok(())
}

#[tauri::command]
async fn open_recent_file(path: String) -> Result<(), String> {
    println!("Opening recent file: {}", path);
    Ok(())
}

#[tauri::command]
async fn exit_app(window: Window) -> Result<(), String> {
    window.close().map_err(|e| e.to_string())?;
    Ok(())
}

#[tauri::command]
async fn minimize_window(window: Window) -> Result<(), String> {
    window.minimize().map_err(|e| e.to_string())?;
    Ok(())
}

#[tauri::command]
async fn toggle_maximize(window: Window) -> Result<(), String> {
    if window.is_maximized().map_err(|e| e.to_string())? {
        window.unmaximize().map_err(|e| e.to_string())?;
    } else {
        window.maximize().map_err(|e| e.to_string())?;
    }
    Ok(())
}

#[tauri::command]
async fn toggle_fullscreen(window: Window) -> Result<(), String> {
    let is_fullscreen = window.is_fullscreen().map_err(|e| e.to_string())?;
    window.set_fullscreen(!is_fullscreen).map_err(|e| e.to_string())?;
    Ok(())
}

#[tauri::command]
async fn create_new_window(_app: tauri::AppHandle) -> Result<(), String> {
    // 在 Tauri 2.0 中，WindowBuilder 需要特殊的特性
    // 暂时返回成功，实际的新窗口功能需要配置 unstable 特性
    println!("Creating new window...");
    Ok(())
}

#[tauri::command]
async fn open_url(url: String) -> Result<(), String> {
    opener::open(url).map_err(|e| e.to_string())?;
    Ok(())
}

#[tauri::command]
async fn open_logs_folder() -> Result<(), String> {
    // 实现打开日志文件夹
    println!("Opening logs folder...");
    Ok(())
}

#[tauri::command]
async fn check_for_updates() -> Result<bool, String> {
    // 实现更新检查逻辑
    println!("Checking for updates...");
    Ok(false) // 暂时返回无更新
}

#[tauri::command]
async fn set_view_mode(mode: String) -> Result<(), String> {
    println!("Setting view mode to: {}", mode);
    Ok(())
}

// 编辑器相关命令
#[tauri::command]
async fn editor_undo() -> Result<(), String> {
    println!("Editor: Undo");
    Ok(())
}

#[tauri::command]
async fn editor_redo() -> Result<(), String> {
    println!("Editor: Redo");
    Ok(())
}

#[tauri::command]
async fn editor_cut() -> Result<(), String> {
    println!("Editor: Cut");
    Ok(())
}

#[tauri::command]
async fn editor_copy() -> Result<(), String> {
    println!("Editor: Copy");
    Ok(())
}

#[tauri::command]
async fn editor_paste() -> Result<(), String> {
    println!("Editor: Paste");
    Ok(())
}

#[tauri::command]
async fn editor_select_all() -> Result<(), String> {
    println!("Editor: Select All");
    Ok(())
}

fn main() {
    // 初始化日志系统
    tracing_subscriber::fmt()
        .with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
        .init();
    
    info!("Starting SocialMatrix Pro");
    
    tauri::Builder::default()
        .manage(AppState::default())
        .manage(DeviceManagerState {
            manager: Arc::new(tokio::sync::Mutex::new(None)),
        })
        .manage(DeviceControlState::new())
        .plugin(tauri_plugin_store::Builder::new().build())
        .plugin(tauri_plugin_fs::init())
        .plugin(tauri_plugin_dialog::init())
        .plugin(tauri_plugin_notification::init())
        .plugin(tauri_plugin_shell::init())
        .plugin(tauri_plugin_clipboard_manager::init())
        .plugin(tauri_plugin_http::init())
        .setup(|app| {
            info!("Setting up application");
            
            // Get app data directory and ensure it exists
            let app_data_dir = app.path().app_data_dir()
                .map_err(|e| format!("Failed to get app data directory: {}", e))?;
            
            // Create data directory if it doesn't exist
            std::fs::create_dir_all(&app_data_dir)
                .map_err(|e| format!("Failed to create app data directory: {}", e))?;
            
            // Initialize database with proper path
            let db_path = app_data_dir.join("app.db");
            // On Windows, ensure the path uses forward slashes for SQLite
            let db_path_str = db_path.to_string_lossy().replace('\\', "/");
            let database_url = format!("sqlite:{}", db_path_str);
            
            info!("Initializing database at: {}", database_url);
            
            let db = tokio::runtime::Runtime::new()
                .unwrap()
                .block_on(async {
                    DatabaseManager::new(&database_url).await
                })
                .map_err(|e| format!("Failed to initialize database: {}", e))?;
            
            app.manage(db);
            
            info!("Application setup completed");
            Ok(())
        })
        .invoke_handler(tauri::generate_handler![
            // ADB设备管理命令
            initialize_device_manager,
            scan_adb_devices,
            connect_adb_device,
            disconnect_adb_device,
            take_device_screenshot,
            get_device_performance,
            get_all_adb_devices,
            
            // 设备控制命令 (Phone Control from scrcpy-mask)
            start_device_control,
            stop_device_control,
            send_touch_event,
            send_key_event,
            send_text_input,
            send_scroll_event,
            send_back_button,
            rotate_device,
            set_clipboard,
            get_clipboard,
            expand_notification_panel,
            expand_settings_panel,
            collapse_panels,
            set_screen_power_mode,
            
            // 数据库管理命令
            get_accounts,
            get_accounts_by_platform,
            create_account,
            assign_account_to_device,
            login_account,
            logout_account,
            verify_account,
            refresh_account_info,
            get_account_stats,
            
            // 任务管理命令
            get_tasks,
            create_task,
            start_task,
            pause_task,
            complete_task,
            fail_task,
            retry_task,
            update_task_progress,
            delete_task,
            get_task_logs,
            add_task_log,
            get_task_stats,
            
            // 内容管理命令
            get_content_library,
            create_content_item,
            update_content_item,
            delete_content_item,
            upload_media,
            generate_thumbnail,
            search_content,
            get_recommended_content,
            mark_content_used,
            rate_content,
            
            // 系统管理命令
            get_system_info,
            get_config,
            set_config,
            get_all_configs,
            health_check,
            get_database_stats,
            backup_database,
            restore_database,
            cleanup_data,
            export_data,
            restart_services,
            
            // 分析统计命令
            get_dashboard_stats,
            get_performance_metrics,
            get_account_analytics,
            get_platform_trends,
            generate_report,
            get_realtime_stats,
            get_historical_comparison,
            get_predictions,
            
            // 设备管理命令
            get_devices,
            create_device,
            get_device,
            delete_device,
            connect_device,
            disconnect_device,
            update_device_status,
            
            // Legacy命令
            hello_world,
            save_app_settings,
            load_app_settings,
            update_recent_files,
            get_app_version,
            show_open_dialog,
            show_save_dialog,
            save_current_project,
            save_project_as,
            open_recent_file,
            exit_app,
            minimize_window,
            toggle_maximize,
            toggle_fullscreen,
            create_new_window,
            open_url,
            open_logs_folder,
            check_for_updates,
            set_view_mode,
            editor_undo,
            editor_redo,
            editor_cut,
            editor_copy,
            editor_paste,
            editor_select_all
        ])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}